﻿package  
{
	import Box2D.Collision.*;
	import Box2D.Dynamics.*;
	import Box2D.Dynamics.Joints.b2DistanceJoint;
	import Box2D.Dynamics.Joints.b2DistanceJointDef;
	import Box2D.Dynamics.Joints.b2Joint;
	import Box2D.Dynamics.Joints.b2RevoluteJoint;
	import Box2D.Dynamics.Joints.b2RevoluteJointDef;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.text.TextField;
	
	/**
	 * ...
	 * @author ...
	 */
	public class vehicle
	{
		public var m_dnaSample:dna;
		public var m_wheel1:wheel;
		public var m_wheel2:wheel;
		public var m_ball1:ball;
		public var m_ball2:ball;
		public var m_joints:Array = new Array();
		public var m_sprite:Sprite = new Sprite();
		public var m_world:b2World;
		
		
		public function vehicle(dnaSample:dna, world:b2World) 
		{	
			m_world = world;
			
			// Initialize Vehicle body object wrappers
			m_wheel1 = new wheel(dnaSample.m_px[0] as Number, dnaSample.m_py[0] as Number, dnaSample.m_radius[0] as Number, world);
			m_wheel2 = new wheel(dnaSample.m_px[1] as Number, dnaSample.m_py[1] as Number, dnaSample.m_radius[1] as Number, world);
			m_ball1 = new ball(dnaSample.m_px[2] as Number, dnaSample.m_py[2] as Number, dnaSample.m_radius[2] as Number, world);
			m_ball2 = new ball(dnaSample.m_px[3] as Number, dnaSample.m_py[3] as Number, dnaSample.m_radius[3] as Number, world);
				 
			
			// Setup Joints
			
			// Revolute/Motor Joints
			var revJointDef:b2RevoluteJointDef = new b2RevoluteJointDef();
			
			// Motor Joint #2
			revJointDef.enableMotor = true;
			revJointDef.motorSpeed = -300 / m_wheel2.m_radius;
			revJointDef.maxMotorTorque = 1000;
			revJointDef.Initialize(m_wheel2.m_wheelBody, m_ball2.m_ballBody, m_wheel2.m_wheelBody.GetPosition());
			m_joints.push(world.CreateJoint(revJointDef));
			
			// Motor Joint #1
			revJointDef.enableMotor = false;
			revJointDef.motorSpeed = 0;
			revJointDef.maxMotorTorque = 1000;
			revJointDef.Initialize(m_wheel1.m_wheelBody, m_ball1.m_ballBody, m_wheel1.m_wheelBody.GetPosition());
			m_joints.push(world.CreateJoint(revJointDef));
			
			// Distance Joints
			var disJointDef:b2DistanceJointDef = new b2DistanceJointDef();
			
			// Dist Joint #1
			disJointDef.Initialize(m_wheel1.m_wheelBody, m_wheel2.m_wheelBody, m_wheel1.m_wheelBody.GetPosition(), m_wheel2.m_wheelBody.GetPosition());
			m_joints.push(world.CreateJoint(disJointDef));
			
			// Dist Joint #2
			disJointDef.Initialize(m_ball1.m_ballBody, m_ball2.m_ballBody, m_ball1.m_ballBody.GetPosition(), m_ball2.m_ballBody.GetPosition());
			m_joints.push(world.CreateJoint(disJointDef));
			
			// Dist Joint #3
			disJointDef.Initialize(m_wheel1.m_wheelBody, m_ball2.m_ballBody, m_wheel1.m_wheelBody.GetPosition(), m_ball2.m_ballBody.GetPosition());
			m_joints.push(world.CreateJoint(disJointDef));
			
			// Dist Joint #4
			disJointDef.Initialize(m_wheel2.m_wheelBody, m_ball1.m_ballBody, m_wheel2.m_wheelBody.GetPosition(), m_ball1.m_ballBody.GetPosition());
			m_joints.push(world.CreateJoint(disJointDef));
			
			
		}
		
		public function getMeanPos():cartesian
		{
			var xSum:Number = 0;
			var ySum:Number = 0;
			
			xSum += m_wheel1.m_pos.x;
			xSum += m_wheel2.m_pos.x;
			
			xSum += m_ball1.m_pos.x;
			xSum += m_ball2.m_pos.x;
			
			ySum += m_wheel1.m_pos.y;
			ySum += m_wheel2.m_pos.y;
			ySum += m_ball1.m_pos.y;
			ySum += m_ball2.m_pos.y;
			
			return new cartesian((xSum / 4), (ySum / 4));
		}
		
		public function update():void
		{
			m_wheel1.update();
			m_wheel2.update();
			m_ball1.update();
			m_ball2.update();
			
			//trace("Wheel Angle: " + m_wheel1.m_angle);
			//trace("Wheel Speed: " + b2RevoluteJoint(m_joints[0]).GetMotorSpeed());
			
		}
		
		public function kill():void
		{
			for (var i:int = 0; i < m_joints.length; i++)
			{
				m_world.DestroyJoint(m_joints[i]);
			}
			
			m_world.DestroyBody(m_wheel1.m_wheelBody);
			m_world.DestroyBody(m_wheel2.m_wheelBody);
			m_world.DestroyBody(m_ball1.m_ballBody);
			m_world.DestroyBody(m_ball2.m_ballBody);
			

		}
		
		public function draw(screen:Sprite, cam:camera):void
		{
			if (!screen.contains(m_sprite))
			{
				screen.addChild(m_sprite);
			}
			
			m_sprite.graphics.clear();
			
			m_wheel1.draw(m_sprite, cam);
			m_wheel2.draw(m_sprite, cam);
			m_ball1.draw(m_sprite, cam);
			m_ball2.draw(m_sprite, cam);
			
			
			// Draw all the joints connecting the pieces
			m_sprite.graphics.lineStyle(1, 11184810);
			for (var i:int = 0; i < m_joints.length; i++)
			{
				var vJoint:b2Joint = (m_joints[i]) as b2Joint;
				var p1:cartesian = new cartesian(vJoint.GetBody1().GetPosition().x * main.m_physScale, vJoint.GetBody1().GetPosition().y * main.m_physScale);
				var p2:cartesian = new cartesian(vJoint.GetBody2().GetPosition().x * main.m_physScale, vJoint.GetBody2().GetPosition().y * main.m_physScale);
				
				m_sprite.graphics.moveTo(p1.toScreen(cam).x, p1.toScreen(cam).y);
				m_sprite.graphics.lineTo(p2.toScreen(cam).x, p2.toScreen(cam).y);
			}
			
		}
		
	}
	
}